from collections import deque
from pygame.locals import *
from graph import Graph
import pygame
import random
import numpy as np

class Snake(object):
    def __init__(self, graph, start_position, food, color = (100,100,100)):
        self.graph = graph #
        self.body = deque()# storage the position of body
        self.size = graph.unit
        self.color = color#(r,g,b)
       
        self.food = food
        self.start_position = start_position # (x_0,y_0)
        self.dx, self.dy = 0,0
        self.grow = False
        self.init() # init of itself



    def init(self):
        self.body.clear()
        self.body.appendleft(self.start_position)
        self.dx, self.dy = 0,0

    
    def move(self):
        head = self.body[0]
        x_cur, y_cur = head[0], head[1]
        x = x_cur + self.dx
        y = y_cur + self.dy
        next_position = (x,y)

        self.move_rule3()

        if next_position == self.food.position:
            self.grow = True # it will grow one unit when it eat a food
            #then update the position of food
            self.food.life = False
            self.food.update()
        if self.position_constraint(x,y):
            self.body.appendleft(next_position)
            #if grow 
            if not self.grow:
                self.body.pop()
            else: self.grow = False

    def position_constraint(self,x,y):
        #connot move out of graph, and cannot touch the body of itself
        if (x >= 0 and x < self.graph.m and y >= 0 and y < self.graph.n)and( (x,y) not in self.body):
            return True
        else:
            return False

    def move_rule(self):
        delta_x = self.body[0][0] - self.food.position[0]
        delta_y = self.body[0][1] - self.food.position[1]
        print(delta_x,delta_y)
        if np.abs(delta_x) > np.abs(delta_y):
            if delta_x < 0: # food at the left of snake
                if((self.body[0][0] + 1, self.body[0][1]) not in self.body):
                    self.move_right()
                else:
                    if delta_y > 0:
                        self.move_up()
                    else:# delta_y < 0:
                        self.move_down()
            elif delta_x > 0:
                if((self.body[0][0] - 1, self.body[0][1]) not in self.body):
                    self.move_left()
                else:
                    if delta_y > 0:
                        self.move_up()
                    else:# delta_y < 0:
                        self.move_down()
        else:
            if delta_y > 0:
                if ((self.body[0][0], self.body[0][1] - 1) not in self.body):
                    self.move_up()
                else:
                    if delta_x > 0:
                        self.move_left()
                    else:# delta_x < 0:
                        self.move_right()
            elif delta_y < 0:
                if ((self.body[0][0], self.body[0][1] + 1) not in self.body):
                    self.move_down()
                else:
                    if delta_x > 0:
                        self.move_left()
                    else:# delta_x < 0:
                        self.move_right()
    def move_rule2(self):
        delta_x = self.body[0][0] - self.food.position[0]
        delta_y = self.body[0][1] - self.food.position[1]

        if delta_x < 0:
            self.move_right()
        elif delta_x > 0:
            self.move_left()
        else:
            if delta_y > 0:
                self.move_up()
            elif delta_y < 0:
                self.move_down()


    def move_rule3(self):
        delta_x = self.body[0][0] - self.food.position[0]
        delta_y = self.body[0][1] - self.food.position[1]

        if delta_x != 0:
            if delta_x < 0 :
                self.move_right()
            else: self.move_left()
        elif delta_y != 0:
            if delta_y > 0:
                self.move_up()
            else:
                self.move_down()
    def move_up(self):
        self.dx = 0
        self.dy = -1
    def move_down(self):
        self.dx = 0
        self.dy = 1

    def move_right(self):
        self.dx = 1
        self.dy = 0
    def move_left(self):
        self.dx = -1
        self.dy = 0
    def key_event(self, key):
        if key[K_w]:
            self.move_up()
        if key[K_s]:
            self.move_down()
        if key[K_a]:
            self.move_left()
        if key[K_d]:
            self.move_right()
        if key[K_u]:
            self.grow = True
        if key[K_r]:
            self.init()
    def display(self, screen):
        for s in self.body:
            x = s[0] * self.size + self.graph.line_width
            y = s[1] * self.size + self.graph.line_width
            l = self.size - self.graph.line_width
            pygame.draw.rect(screen, self.color, (x,y,l,l),0)


